<template>
  <div
    class="image-uploader-container"
  >
  <PreviewItem
      v-for="(fileItem, index) in value"
      :key="index"
      :url="fileItem.url"
      image-fit="cover"
      @click="clickPreview(fileItem, index)"
      @delete="onDelete(index)"
    />

    <PreviewItem
      v-for="(task, index) in tasks"
      :key="index"
      :file="task.file"
      :deletable="task.status !== 'pending'"
      :status="task.status"
      @delete="onTaskDelete(task)"
    />

    <div
      v-if="value.length + tasks.length < maxCount"
      class="image-uploader-upload-button-wrap"
    >
      <div class="image-add-img">
        <span
              class="img-upload-button"
              role="button"
              aria-label="上传"
              @click="clickadd"
            >
            <img class="up-img-icon" src="//www.xnbz.site/static/file/add.png" alt="" srcset="">
            </span>
         
        </div>

    </div>
  </div>
</template>

<script>
import PreviewItem from "./previewItem.vue"
import { hostPrefix } from '@/config'

let current = 0

// 上传文件
export const uploadFiles = async (file, flagtip, username) => {

  return new Promise((resolve)=>{
        //  //图片上传
        wx.uploadFile({
            url: hostPrefix + '/api/file/upload',
            filePath: file.tempFilePath,
            name: 'photo',
            formData: {
                flagtip,
                username,
            },
            success(res) {
              const imgurl = JSON.parse(res.data).wxUrl
              if(imgurl){
                // 解决微信上传接口乱码问题
                return resolve({url: decodeURIComponent(imgurl)})
              }
            },
            fail(res) {
              console.log('error', res)
            },
          })
  })
}

export default {
  name: "ImageUploader",
  components: {
    PreviewItem,
  },
  model: {
    prop: "value",
    event: "change",
  },
  props: {
    // 传递文件名信息，保存的服务器磁盘的时候，更好区分，属于业务逻辑，可以不用
    flagtip: {
      type: String,
      default: undefined,
    },
    capture: {
      type: String,
      default: undefined,
    },
    accept: {
      type: String,
      default: undefined,
    },
    multiple: {
      type: Boolean,
      default: false,
    },
    maxCount: {
      type: Number,
      default: 6,
    },
    value: {
      type: Array,
      default: () => [],
    },
  
  },
  data() {
    return {
      loading: false,
      // 用于储存 正在加载中的照片， 每次加载好一个照片，就会将加载好的照片，添加到 setValue 中，
      // 然后再监听 value 变化，从tasks中删除对应的照片
      tasks: [],
    }
  },
  watch: {
    // 然后再监听 value 变化，从tasks中删除对应的照片
    value(vals) {
      console.log(this.tasks)
      this.tasks = this.tasks.filter(task => {
        if (task.url === undefined) return true
        return !vals.some(fileItem => fileItem.url === task.url)
      })
    },
   
  },
  methods: {
    clickadd() {
      const that = this
      uni.chooseMedia({
      count: 9,
      mediaType: ['image'],
      sourceType: ['album', 'camera'],
      // maxDuration: 30,
      success(res) {
        that.onChange(res.tempFiles || [])
      },
      fail(res) {
        console.log('error', res)
      }
    })
    },
    clickPreview(item, index) {
      uni.previewImage({
        urls: this.value.map(t=> t.url),
        current: index,
        longPressActions: {
          itemList: ['发送给朋友', '保存图片', '收藏'],
          success: function(data) {
            console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片');
          },
          fail: function(err) {
            console.log(err.errMsg);
          }
        }
      })
    },
    beforeUpload(file) {
      // // 尺寸不超过 5M
      if (file.size > Number(5) * 1024 * 1024) {
        console.log("图片超出最大值")
        // Toast.info("图片超出最大值")
        return Promise.resolve(null)
      }
      return Promise.resolve(file)
    },
    async processFile(file, fileList) {
      let transformedFile = file

      transformedFile = await this.beforeUpload?.(file, fileList)

      return transformedFile
    },
    async mockUpload(file) {
      const res = await uploadFiles(file, this.flagtip, this.$store.getters.userInfo.username)

      if (res && res.url) {
        return { url: res.url }
      }

      throw new Error("图片上传失败")
    },
    async onChange(rawFiles) {
      let files = [].slice.call(rawFiles)

      const postFiles = files.map(file => {
        return this.processFile(file, files)
      })

      await Promise.all(postFiles).then(filesList => {
        files = filesList.filter(Boolean)
      })

      if (files.length === 0) {
        return
      }

      if (this.maxCount > 0) {
        const exceed = this.value.length + files.length - this.maxCount
        if (exceed > 0) {
          files = files.slice(0, files.length - exceed)
        }
      }

      const newTasks = files.map(file => ({
        id: `__imageupload__${current++}`,
        status: "pending",
        file,
      }))

      this.tasks = [...this.tasks, ...newTasks]
      await Promise.all(
        newTasks.map(async currentTask => {
          try {
            const result = await this.mockUpload(currentTask.file)
            this.tasks = this.tasks.map(task => {
              if (task.id === currentTask.id) {
                return {
                  ...task,
                  status: "success",
                  url: result.url,
                }
              }
              return task
            })

            // 用于储存 正在加载中的照片， 每次加载好一个照片，就会将加载好的照片，添加到 setValue 中 ，
            // 然后再监听 value 变化，从tasks中删除对应的照片

            this.$emit("change", [...this.value, { ...result }])
          } catch (e) {
            this.tasks = this.tasks.map(task => {
              if (task.id === currentTask.id) {
                return {
                  ...task,
                  status: "fail",
                }
              }
              return task
            })

            // 必要的时候，考虑将报错抛出去
            // throw e
            console.warn(e)
          }
        }),
      ).catch(error => console.error(error))
    },
    onDelete(index) {
      this.$emit(
        "change",
        this.value.filter((x, i) => i !== index),
      )
    },
    onTaskDelete(task) {
      this.tasks = this.tasks.filter(x => x.id !== task.id)
    },
  },
}
</script>

<style lang="less">
.image-uploader-container {
  width: 100%;
  display: flex;
  overflow-x: auto;
  touch-action: pan-x;
  .image-uploader-upload-button-wrap {
    flex-shrink: 0;
    display: inline-block;
    height: 107px;
    width: 107px;
    border-radius: 8px;
    margin-right: 11px;
    background: #f5f7f9;
  }

  .image-add-img {
    width: 100%;
    height: 100%;
    position: relative;
  }
  .img-upload-input{
    cursor: pointer;
      position: absolute;
      opacity: 0;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      border-radius: 4px;
  }
  .img-upload-button{
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
  }
  .up-img-icon{
        width: 100%;
        height: 100%;
  }
}
</style>
